<?php
/**
 *	FILENAME: 		/libraries/mynova.php
 *	DESCRIPTION:	This library that uses the PHP Snoopy library to interact with Villanova's MyNova system.
 *	AUTHOR:			Casey Burkhardt
 *	VERSION:		1.0.0
 *	LAST MODIFIED:	12/30/2009
 **/

/**
 THIS SCRIPT IS UNSTABLE AND SITLL UNDER DEVELOPMENT.
 ITS USE IS EXPERIMENTAL AND SHOULD NOT BE USED IN PRODUCTION AT THIS TIME.
 **/
die();

require_once($_SERVER['DOCUMENT_ROOT'] . "/libraries/Snoopy.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/config/environment.php");

function parseCookie($val) {
    $equalsSign = strpos($val, "=");
    $cookieName = substr($val, strlen("Set-Cookie: "), $equalsSign - strlen("Set-Cookie: "));
    $semiColon = strpos($val, ";");
    $cookieValue = substr($val, $equalsSign + 1, $semiColon - $equalsSign - 1);
    $result[$cookieName] = $cookieValue;
    return $result;
}

/**
 *	DESCRIPTION:	Creates a valid MyNova authenticated session.
 **/
function createMyNovaSession($userName, $password) {

    // We start by posting the user supplied login information to the MyNova Login Form.
    // Create a new instance of Snoopy, the page fetching / parsing engine.
    $loginPage = new Snoopy;

    // Set a timeout, in case this thing doesn't work
    $loginPage -> read_timeout = 5;

    // We will need to fetch pages using HTTPS, so we must point Snoopy to our instance of cURL.
    // This information is stored in our environment configuration.
    $loginPage -> curl_path = getCurlPath();

    // Set up appropriate Header Types, We'll reuse these...
    $rawHeaders["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
    $rawHeaders["Accept-Language"] = "en-us,en;q=0.5";
    $rawHeaders["Accept-Encoding"] = "gzip,deflate";
    $rawHeaders["Accept-Charset"] = "ISO-8859-1,utf-8;q=0.7,*;q=0.7";
    $rawHeaders["Keep-Alive"] = "300";
    $rawHeaders["Connection"] = "keep-alive";

    $loginPage -> rawheaders = $rawHeaders;

    if ($loginPage -> fetch("https://novanet.villanova.edu/cp/home/displaylogin")) {
        while(list($key,$val) = each($loginPage->headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $loginPage -> cookies = array_merge($loginPage -> cookies, parseCookie($val));
            }
            echo $key.": ".$val."<br>\n";
        }
        echo "<p>\n";
        //		echo "<PRE>".htmlspecialchars($loginPage->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$loginPage->error."\n";
        die();
    }

    // Cookies will need to be carried over to the next request, so we'll store them here.
    $cookiesSoFar = $loginPage -> cookies;

    // Debugging
    echo "<br /><br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";

    // Now we submit the login information.
    $loginSubmission = new Snoopy;
    $loginSubmission -> read_timeout = 5;
    $loginSubmission -> curl_path = getCurlPath();
    $loginSubmission -> cookies = $cookiesSoFar;
    $loginSubmission -> rawheaders = $rawHeaders;

    // Populate the data for the POST request.
    $submitVars["user"] = $userName;
    $submitVars["pass"] = $password;

    if ($loginSubmission -> submit("https://novanet.villanova.edu/cp/home/login", $submitVars)) {
        while(list($key,$val) = each($loginSubmission->headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $loginSubmission -> cookies = array_merge($loginSubmission -> cookies, parseCookie($val));
            }
            echo $key.": ".$val."<br>\n";
        }
        echo "<p>\n";
        echo "<PRE>".htmlspecialchars($loginSubmission->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$loginSubmission->error."\n";
        die();
    }

    // Cookies will need to be carried over to the next request, so we'll store them here.
    $cookiesSoFar = $loginSubmission -> cookies;

    // Debugging
    echo "<br /><br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";

    // We'll now request the login success page.
    $authPage = new Snoopy;
    $authPage -> read_timeout = 5;
    $authPage -> curl_path = getCurlPath();
    $authPage -> cookies = $cookiesSoFar;
    $authPage -> rawheaders = $rawHeaders;

    if ($authPage -> fetch("https://novanet.villanova.edu/cps/welcome/loginok.html")) {
        while(list($key, $val) = each($authPage -> headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $authPage -> cookies = array_merge($authPage -> cookies, parseCookie($val));
            }
            echo $key . ": " . $val . "<br>\n";
        }
        echo "<p>\n";
        echo "<PRE>".htmlspecialchars($authPage->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$authPage->error."\n";
        die();
    }

    // Cookies will need to be carried over to the next request, so we'll store them here.
    $cookiesSoFar = $authPage -> cookies;

    // Debugging
    echo "<br /><br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";

    // We'll now request the next login success page.
    $authPage2 = new Snoopy;
    $authPage2 -> read_timeout = 5;
    $authPage2 -> curl_path = getCurlPath();
    $authPage2 -> cookies = $cookiesSoFar;
    $authPage2 -> rawheaders = $rawHeaders;

    if ($authPage2 -> fetch("https://novanet.villanova.edu/cp/home/next")) {
        while(list($key, $val) = each($authPage2 -> headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $authPage2 -> cookies = array_merge($authPage2 -> cookies, parseCookie($val));
            }
            echo $key . ": " . $val . "<br>\n";
        }
        echo "<p>\n";
        echo "<PRE>".htmlspecialchars($authPage2->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$authPage2->error."\n";
        die();
    }

    // Cookies will need to be carried over to the next request, so we'll store them here.
    $cookiesSoFar = $authPage2 -> cookies;

    // Debugging
    echo "<br /><br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";

    // We'll now request the next, and hopefully last login success page.
    $authPage3 = new Snoopy;
    $authPage3 -> read_timeout = 5;
    $authPage3 -> curl_path = getCurlPath();
    $authPage3 -> cookies = $cookiesSoFar;
    $authPage3 -> rawheaders = $rawHeaders;

    $submitMe["uP_root"] = "root";

    if ($authPage3 -> submit("https://novanet.villanova.edu/render.userLayoutRootNode.uP", $submitMe)) {
        while(list($key, $val) = each($authPage3 -> headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $authPage3 -> cookies = array_merge($authPage3 -> cookies, parseCookie($val));
            }
            echo $key . ": " . $val . "<br>\n";
        }
        echo "<p>\n";
        echo "<PRE>".htmlspecialchars($authPage3->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$authPage3->error."\n";
        die();
    }

    // Cookies will need to be carried over to the next request, so we'll store them here.
    $cookiesSoFar = $authPage3 -> cookies;

    // Debugging
    echo "<br /><br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";

    // Finally, we'll request the courses page.
    $coursesPage = new Snoopy;
    $coursesPage -> read_timeout = 5;
    $coursesPage -> curl_path = getCurlPath();
    $coursesPage -> cookies = $cookiesSoFar;
    $coursesPage -> rawheaders = $rawHeaders;

    $submitMe["uP_root"] = "u12l1n30";
    $submitMe["padding"] = "true";

    if ($coursesPage -> submit("https://novanet.villanova.edu/render.userLayoutRootNode.uP", $submitMe)) {
        while(list($key, $val) = each($coursesPage -> headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $coursesPage -> cookies = array_merge($coursesPage -> cookies, parseCookie($val));
            }
            echo $key . ": " . $val . "<br>\n";
        }
        echo "<p>\n";
        echo "<PRE>".htmlspecialchars($coursesPage->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$coursesPage->error."\n";
        die();
    }

    // Cookies will need to be carried over to the next request, so we'll store them here.
    $cookiesSoFar = $coursesPage -> cookies;

    // Debugging
    echo "<br /><br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";

    // That course page actually works, but doesn't contain all the information we need.
    // We're giong to utilize UNIT's security loophole into NOVASIS to access the entire current course list.
    // Let's parse the URL that we actually want from the last response.

    $startIndex = strpos($coursesPage -> results, '<tr><td class="uportal-text"><TR><TD class="uportal-text"><a href="') + strlen('<tr><td class="uportal-text"><TR><TD class="uportal-text"><a href="');
    $endIndex = strpos($coursesPage -> results, '"', $startIndex);
    $url = substr($coursesPage -> results, $startIndex, $endIndex - $startIndex);
    $url = "https://novanet.villanova.edu/" . $url;

    // Now that we have the URL, we must seperate the GET Parameters out and pass them to the server in the final request as POST parameters.
    // There are only two paramaters, so it's easiest to parse by hand.
    // First Parameter
    $fPNStartIndex = strpos($url, "?") + 1;
    $fPNEndIndex = strpos($url, "=");
    $firstParamName = substr($url, $fPNStartIndex, $fPNEndIndex - $fPNStartIndex);
    echo "<br /><br />START: " . $fPNStartIndex . " END: " . $fPNEndIndex . " NAME WAS: " . $firstParamName;
    $fPVStartIndex = $fPNEndIndex + 1;
    $fPVEndIndex = strpos($url, "&", $fPVStartIndex);
    $firstParamValue = substr($url, $fPVStartIndex, $fPVEndIndex - $fPVStartIndex);
    echo "<br /><br />START: " . $fPVStartIndex . " END: " . $fPVEndIndex . " NAME WAS: " . $firstParamValue;
    $finalPostVars[$firstParamName] = $firstParamValue;

    // Second Parameter
    $sPNStartIndex = strpos($url, "&", $fPVStartIndex) + 5;
    $sPNEndIndex = strpos($url, "=", $sPNStartIndex);
    $secondParamName = substr($url, $sPNStartIndex, $sPNEndIndex - $sPNStartIndex);
    echo "<br /><br />START: " . $sPNStartIndex . " END: " . $sPNEndIndex . " NAME WAS: " . $secondParamName;
    $sPVStartIndex = $sPNEndIndex + 1;
    $secondParamValue = substr($url, $sPVStartIndex);
    echo "<br /><br />START: " . $sPVStartIndex . " NAME WAS: " . $secondParamValue;
    $finalPostVars[$secondParamName] = $secondParamValue;

    echo "<br /><br />Request URL: " . $url;
    echo "<br /><br />Final Post Vars: <br />";
    print_r($finalPostVars);

    // Now remove all the parameters from the actual URL so it can be requested properly.
    $url = substr($url, 0, strpos($url, "?"));
    echo "Shortened URL: " . $url;

    $coursesDetailPage = new Snoopy;
    $coursesDetailPage -> read_timeout = 5;
    $coursesDetailPage -> curl_path = getCurlPath();
    $coursesDetailPage -> cookies = $cookiesSoFar;
    $coursesDetailPage -> rawheaders = $rawHeaders;


    if ($coursesDetailPage -> submit($url, $finalPostVars)) {
        while(list($key, $val) = each($coursesDetailPage -> headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $coursesDetailPage -> cookies = array_merge($coursesDetailPage -> cookies, parseCookie($val));
            }
            echo $key . ": " . $val . "<br>\n";
        }
        echo "<p>\n";
        echo "<PRE>".htmlspecialchars($coursesDetailPage->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$coursesDetailPage->error."\n";
        die();
    }

    // Cookies will need to be carried over to the next request, so we'll store them here.
    $cookiesSoFar = $coursesDetailPage -> cookies;

    // Debugging
    echo "<br />THAT WAS IT<br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";

}
?>